<?php
/**
 * Created by PhpStorm.
 * User: syzhou
 * Date: 2019-10-16
 * Time: 15:01
 */

namespace App\Http\Controllers;


use App\ReviewerGroupProject;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Request;

class DefenseReviewAPIController extends Controller
{
    public function getProjects() {
        $defenseProjectIds = [83,136,222,338,359,452,461,585,841];
        $projects = DB::table('meeting_review_reviewers as a')
            ->leftJoin('meeting_review_projects_new as b', 'a.large_group_id', '=', 'b.large_group_id')
            ->leftJoin('applications as c', 'b.project_id', '=', 'c.id')
            ->leftJoin('users as d', 'c.user_id', '=', 'd.id')
            ->whereIn('c.id', $defenseProjectIds)
            ->select('c.id as project_id', 'c.project_name', 'c.prof_category', 'c.avg_score',
                'b.review_status as meeting_review_status', 'd.name as applicant')
            ->get()->toArray();
        $projectIds = [];
        $projectId2Project = [];
        foreach ($projects as $project) {
            $projectId = $project->project_id;
            $projectIds[] = $projectId;
            $projectId2Project[$projectId] = $project;
        }

        $rows = DB::table('reviewer_score_projects as a')
            ->whereIn('a.project_id', $projectIds)
            ->leftJoin('applications as b', 'a.project_id', '=', 'b.id')
            ->select('a.project_id', 'a.reviewer_id', 'a.reviewer_group_id', 'a.reviewer_group_review_order',
                'a.score_time_cost', 'a.score', 'a.is_submitted', 'a.is_evidence_material_valid', 'a.remark')
            ->get()->toArray();
        foreach ($rows as $row) {
            $projectId = $row->project_id;
            $project = $projectId2Project[$projectId];
            if (!isset($project->score_per_reviewer)) {
                $project->scores_normal = null;
                $project->scores_desc = null;
                $project->score_per_reviewer = [];
            }
            $project->score_per_reviewer[] = $row->is_submitted ? (object)[
                'reviewer_id' => $row->reviewer_id,
                'score_time_cost' => $row->score_time_cost,
                'score' => $row->score,
                'is_evidence_material_valid' => $row->is_evidence_material_valid,
                'remark' => $row->remark,
            ] : (object)[
                'reviewer_id' => $row->reviewer_id,
                'score_time_cost' => null,
                'score' => null,
                'is_evidence_material_valid' => null,
                'remark' => null,
            ];
        }

        // 计算专家组各专家评分的分值状态
        foreach ($projectId2Project as $project) {
            $reviewerScores = array_map(function ($reviewerScore) {
                return $reviewerScore->score;
            }, $project->score_per_reviewer);
            $scoresState = ReviewerGroupProject::calcScoresState($reviewerScores);
            $project->scores_normal = $scoresState['ok'];
            $project->scores_desc = $scoresState['desc'];
            $project->scores_standard_deviation = $this->calcStandardDeviation($reviewerScores);
        }

        $projects = array_values($projectId2Project);
        usort($projects, function ($a, $b) {
            $a = $a->avg_score;
            $b = $b->avg_score;
            return $a > $b ? -1 : ($a == $b ? 0 : 1);
        });
        return $this->json([
            'ok' => true,
            'projects' => $projects,
        ]);
    }

    private function calcStandardDeviation($reviewerScores) {
        $n = count($reviewerScores);
        $avg = array_sum($reviewerScores ) / $n;
        $squareErrorSum = 0;
        foreach ($reviewerScores as $score) {
            $diff = $score - $avg;
            $squareErrorSum += $diff * $diff;
        }
        $standardDeviation = round(sqrt($squareErrorSum / ($n-1)), 2);
        return $standardDeviation;
    }

}